using Light;
using Light.Assets.Scripts.EventManager;
using UnityEngine;
using Weapons;

public class Player : MonoBehaviour
{
    private bool isInit;

    #region Set Functions

    public void SetCollisionHeight(float height)
    {
        var center = Collider.offset;
        workspace.Set(Collider.size.x, height);
        center.y += (height - Collider.size.y) / 2;

        Collider.size = workspace;
        Collider.offset = center;
    }

    #endregion Set Functions

    #region State variable

    public PlayerSM StateMechine { get; private set; }

    public PlayerIdleState IdleState { get; private set; }

    public PlayerMoveState MoveState { get; private set; }
    public PlayerJumpState JumpState { get; private set; }
    public PlayerInAirState InAirState { get; private set; }
    public PlayerLandState LandState { get; private set; }
    public PlayerWallclimbState WallClimbState { get; private set; }
    public PlayerWallGrabState WallGrabState { get; private set; }
    public PlayerWallSlideState WallSlideState { get; private set; }
    public PlayerWallJumpState WallJumpState { get; private set; }
    public PlayerLedgeClimbState LedgeClimbState { get; private set; }
    public PlayerDashState DashState { get; private set; }
    public PlayerCrouchIdleState CrouchIdleState { get; private set; }
    public PlayerCrouchMoveState CrouchMoveState { get; private set; }
    public PlayerAttackState PrimaryAttackState { get; private set; }
    public PlayerAttackState SecondAttackState { get; }

    [SerializeField] private PlayerData _playerData;

    #endregion State variable

    #region Component

    public Core Core { get; private set; }
    public Animator Anim { get; private set; }
    public Rigidbody2D _rb { get; private set; }

    public BoxCollider2D Collider { get; private set; }

    public Transform _dashDirectionIndicatior { get; private set; }
    [SerializeField] private PlayerInventory _playerInventory;
    [HideInInspector] public LightInputManager _playerInputHander;

    #endregion Component

    #region Other Variable

    public Vector2 CollisionSize { get; }
    public Vector2 CollisionMidSize { get; }
    public Vector2 CurrentCollisionSize { get; }

    private Vector2 _velocity;

    private Vector2 workspace;

    private NewWeapon _primaryWeapon;
    private NewWeapon _secondaryWeapon;

    #endregion Other Variable

    #region Unity Callback Funtions

    private void Awake()
    {
        Core = GetComponentInChildren<Core>();
        _primaryWeapon = transform.Find("Weapons").transform.Find("PrimaryWeapon").GetComponent<NewWeapon>();
        //_secondaryWeapon = transform.Find("Weapons").transform.Find("SecondaryWeapon").GetComponent<NewWeapon>();

        //Ϊ�ڹ���״̬�������˶�����Core����
        _primaryWeapon.SetCore(Core);
        //_secondaryWeapon.SetCore(Core);

        StateMechine = new PlayerSM();
        StateRegister();
    }

    private void StateRegister()
    {
        IdleState = new PlayerIdleState(this, StateMechine, _playerData, "Idle", Core);
        MoveState = new PlayerMoveState(this, StateMechine, _playerData, "Move", Core);
        CrouchIdleState = new PlayerCrouchIdleState(this, StateMechine, _playerData, "CrouchIdle", Core);
        CrouchMoveState = new PlayerCrouchMoveState(this, StateMechine, _playerData, "CrouchMove", Core);

        JumpState = new PlayerJumpState(this, StateMechine, _playerData, "InAir", Core);
        InAirState = new PlayerInAirState(this, StateMechine, _playerData, "InAir", Core);
        LandState = new PlayerLandState(this, StateMechine, _playerData, "Land", Core);

        WallClimbState = new PlayerWallclimbState(this, StateMechine, _playerData, "WallClimb", Core);
        WallGrabState = new PlayerWallGrabState(this, StateMechine, _playerData, "WallGrab", Core);
        WallSlideState = new PlayerWallSlideState(this, StateMechine, _playerData, "WallSlide", Core);
        WallJumpState = new PlayerWallJumpState(this, StateMechine, _playerData, "WallJump", Core);

        LedgeClimbState = new PlayerLedgeClimbState(this, StateMechine, _playerData, "Hanging", Core);
        DashState = new PlayerDashState(this, StateMechine, _playerData, "Dash", Core);

        PrimaryAttackState = new PlayerAttackState(this, StateMechine, _playerData, "Attack", Core, _primaryWeapon,
            CombatInputs.Primary);
        //SecondAttackState = new PlayerAttackState(this, StateMechine, _playerData, "Attack", Core, _secondaryWeapon, CombatInputs.Secondary);
    }

    private void Start()
    {
        _rb = GetComponent<Rigidbody2D>();
        Anim = GetComponentInChildren<Animator>();
        _playerInputHander = GetComponentInChildren<LightInputManager>();
        Collider = GetComponentInChildren<BoxCollider2D>();
        _playerInventory = GetComponent<PlayerInventory>();
        _dashDirectionIndicatior = transform.Find("DashDirectionIndicator");

        //PrimaryAttackState.SetWeapon(_playerInventory._weapons[(int)CombatInputs.Primary]);
        //PrimaryAttackState.WeapoInitial(); ԭ���ڳ�ʼ������������������Player��ײ�еĸ߶ȴ��ݸ�����

        isInit = true;

        //TODO: Init StateMechine
        StateMechine.Initialize(IdleState);


        //�㲥Playerע��ɹ�
        using var evt = PlayerRegisterEvent.Get(); //ʹ��using�ڳ�����������Զ�����Dispose��������

        evt.transform = transform;
        EventManager.SendEvent(evt);
    }

    private void Update()
    {
        Core.LoginUpdate();
        StateMechine.CurrentState.LogicUpdate();
    }

    private void FixedUpdate()
    {
        StateMechine.CurrentState.PhysicsUpdate();
    }

    private void OnDrawGizmos()
    {
        if (!isInit) return;
        Gizmos.DrawWireCube(Core.Collision.CeilingCheck.position, _playerData._ceilingCheckSize);
        Gizmos.DrawWireCube(Core.Collision.GroundCheck.position, _playerData._groundCheckSize);
    }

    #endregion Unity Callback Funtions

    #region Other Funcions

    //AnimationTrigger�����ڿγ����ɶ����¼�����

    private void AnimationTrigger()
    {
        StateMechine.CurrentState.AnimationTrigger();
    }

    private void AnimationFinshTrigger()
    {
        StateMechine.CurrentState.AnimationFinshTrigger();
    }

    #endregion Other Funcions
}